using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

using tp1.Entidades;

namespace tp1
{
    enum Tipo { RECTA, POLIGONO, CIRCULO };

    class Pipeline
    {
        private static Viewport viewport = new Viewport();
        private static int paso = 1; //Paso de separacion de puntos para la creacion del circulo

        public static void Dibujar(Tipo tipo, List<Punto> lista)
        {
            if (lista.Count < 2)
            {
                throw new Exception("Se deben ingresar al menos dos puntos.");
            }


            List<List<Punto>> listaProcesamiento = new List<List<Punto>>();

            if (tipo == Tipo.CIRCULO)
            {
                Punto centro = null;
                Punto extremo = null;
                foreach (Punto punto in lista)
                {
                    if (centro == null)
                    {
                        centro = punto;
                    }
                    else if (extremo == null)
                    {
                        extremo = punto;

                        int radio = (int)Math.Sqrt(Math.Pow((centro.X - extremo.X), 2.0) + Math.Pow((centro.Y - extremo.Y), 2.0));

                        listaProcesamiento.Add(new List<Punto>(Circulos.PuntosCirculo(centro, radio, paso)));

                        centro = null;
                        extremo = null;
                    }
                }
            }
            else
            {
                listaProcesamiento.Add(lista);
            }

            foreach (List<Punto> listado in listaProcesamiento)
            {
                List<Punto> listaAux = new List<Punto>();
                foreach (Punto punto in listado)
                {
                    //Transformacion de Modelado
                    Punto puntoAux = Transformaciones.MatrizDeTransformacion * punto;
                    //Transformacion de Vista
                    listaAux.Add(viewport.MatrizTWV * puntoAux);
                }

                //Clipping
                //Primitiva 2D
                switch (tipo)
                {
                    case Tipo.RECTA:
                        listaAux = Clipping.RecortarSegmento(listaAux[0], listaAux[1], viewport);
                        if (listaAux.Count > 1)
                        {
                            Primitivas2D.Segmento(listaAux[0], listaAux[1]);
                        }
                        break;
                    case Tipo.CIRCULO:
                    case Tipo.POLIGONO:
                        listaAux = Clipping.RecortarPoligono(listaAux, viewport);
                        if (listaAux.Count > 1)
                        {
                            Primitivas2D.Rellenar(listaAux);
                            Punto puntoInicial = listaAux[listaAux.Count - 1];
                            foreach (Punto puntoFinal in listaAux)
                            {
                                Primitivas2D.Segmento(puntoInicial, puntoFinal);
                                puntoInicial = puntoFinal;
                            }
                        }
                        break;
                }
            }
        }

        #region Transformacion de Modelado
        public static void Escalar(double escaladoX, double escaladoY)
        {
            Transformaciones.AgregarEscalado(escaladoX, escaladoY);
        }

        public static void Trasladar(double traslacionX, double traslacionY)
        {
            Transformaciones.AgregarTraslacion(traslacionX, traslacionY);
        }

        public static void Rotar(double angulo)
        {
            Transformaciones.AgregarRotacion(angulo);
        }

        public static void CargarIdentidad()
        {
            Transformaciones.CargarIdentidad();
        }

        public static void PushM()
        {
            Transformaciones.PushMatrix();
        }

        public static void PopM()
        {
            Transformaciones.PopMatrix();
        }
        #endregion

        #region Transformacion de Vista
        public static void Viewport(int xi, int xd, int ya, int yb)
        {
            viewport.DefinirViewport(xi, xd, ya, yb);
        }

        public static void WorldWindow(double xi, double xd, double ya, double yb)
        {
            viewport.DefinirVista(xi, xd, ya, yb);
        }
        #endregion

        #region Primitivas 2D
        public static void FillColor(Color color)
        {
            Primitivas2D.FillColor((float)(1.0F - ((255.0F - color.R) / 255.0F)),
                (float)(1.0 - ((255.0 - color.G) / 255.0)),
                (float)(1.0 - ((255.0 - color.B) / 255.0)));
        }

        public static void LineColor(Color color)
        {
            Primitivas2D.LineColor((float)(1.0F - ((255.0F - color.R) / 255.0F)),
                (float)(1.0 - ((255.0 - color.G) / 255.0)),
                (float)(1.0 - ((255.0 - color.B) / 255.0)));
        }
        #endregion
    }
}
